/**
 *
 */
package com.dxt.common;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;


/**
 *@description UIP解密工具
 *加解密协议 DES3
 *【加密机制：
 *	1.对全部报文进行公匙加密，
 * 2.再对其中的业务数据进行私匙加密。
 *】
 *
 *
 *@auther lifei7@asiainfo.com
 *
 *@createTime 2015年3月9日下午4:57:13
 *
 */

public class DecryptUtil {
	private static transient Log log = LogFactory.getLog(DecryptUtil.class);
	public  static String PUB_ORGID = "10000";
	private static String charset = "UTF-8";
	/**
	 * 统一接口DES3解密工具
	 *
	 * @param pubKey  		公钥  通用密匙 必传
	 * @param privateKey 	私钥   各第三方的密匙，传空则会根据报文中的orgId从数据库里查询
	 * @param source			加密后的报文
	 * @return						解密的报文
	 * @throws Exception
	 *
	 * String
	 */
	public static String decryptDES3(String pubKey, String privateKey, String source) throws Exception{
		boolean privateCrypt = false;
		String outStr;
		/****0 获取公匙**********/
		if(pubKey == null){
			log.error("查不到公匙信息");
			throw new Exception();
		}
		/****1全文进行解密 得到组织id**********/
		String allContent= new String(DES3Util.trides_decrypt(DES3Util.hexToBytes(pubKey), DES3Util.hexToBytes(source)),charset).trim();
/*		*//****2 根据组织id获取私匙**********//*
		String orgId = getParamValue(allContent, Constant.PublicInfo.ORGID);
		if(StringUtils.isNotBlank(orgId)){
			privateCrypt = true;
		}
		// 如果orgId不为空或者null，解密业务报文。
		if(privateCrypt){

			if(StringUtils.isBlank(privateKey)){
				privateKey = getKeyByOrgId(orgId);
				if(StringUtils.isBlank(privateKey)){
					log.error("查不到私匙信息:orgId = "+orgId);
					throw new Exception();
				}

			}
			*//**** 3 对业务报文进行解密  ****//*
			String req = getParamValue(allContent,"Request");
			String reqD = new String(DES3Util.trides_decrypt(DES3Util.hexToBytes(privateKey), DES3Util.hexToBytes(req)),charset).trim();
			outStr = allContent.replace("\""+req+"\"", reqD);
		}else{*/
			outStr = allContent;
		//}


		return outStr;
	}
	/**
	 * 统一接口DES3加密工具
	 *
	 * @param pubKey  		公钥  通用密匙 必传
	 * @param privateKey 	私钥   各第三方的密匙，传空则不进行业务报文的私钥加密
	 * @param source			加密前的报文
	 * @return						加密后的报文
	 * @throws Exception
	 *
	 * String
	 */
	public static String encryptDES3(String pubKey, String privateKey, String source) throws UnsupportedEncodingException{

		boolean privateCrypt = false;
		if(StringUtils.isNotBlank(privateKey)){
			privateCrypt = true;
		}
		String src2;
		//如果私钥不为空
		if(privateCrypt){
			//1.业务报文加密
			String srcReq = getParamValue(source, "Request");
			String desReq = DES3Util.byte2hex(DES3Util.trides_crypt(DES3Util.hexToBytes(privateKey) ,srcReq.getBytes(charset)));

			//2 替换
			src2 = source.replace(srcReq, "\""+desReq+"\"");
		}else{
			src2 = source;
		}

		//3 公匙全文加密
		String des  =  DES3Util.byte2hex(DES3Util.trides_crypt(DES3Util.hexToBytes(pubKey), src2.getBytes(charset)));
		return des;
	}

/*	public static String getKeyByOrgId(String orgId) throws Exception{
		//获取对应第三方的密钥
		IBaseUipOutSecSV outSecSV = (IBaseUipOutSecSV) ServiceFactory.getService(IBaseUipOutSecSV.class);
		IBOBsUIPOutSecValue outSecValue = outSecSV.getSecFromCache(orgId);
		//如果查不到对应密匙
		if(outSecValue == null){
			log.error("查不到对应的密匙:"+orgId);
			return null;
		}
		String secretKey = outSecValue.getSecretkey();
		return secretKey;
	}*/


	 public static SecretKey getSecretKey(String algorithm,String pwd) throws Exception{
	        SecureRandom secureRandom =SecureRandom.getInstance(algorithm);//SecureRandom.getInstance("SHA1PRNG");
	        secureRandom.setSeed(pwd.getBytes());
	        KeyGenerator generator = KeyGenerator.getInstance("DESede");
	        generator.init(128, secureRandom);
	        SecretKey secretKey = generator.generateKey();
	        return secretKey;
	    }




	public static void main(String[] args) throws Exception {
/*		String src = "{ \"Request\"         : {  \"BusiParams\"      : {   \"Password\"        : \"123321\",   \"ServiceNum\"      : \"17090812118\"  },  \"BusiCode\"        : \"OI_VerifyUserPassword\" }, \"PubInfo\"         : {  \"InterfaceId\"     : \"\",  \"TransactionId\"   : \"APP20150309140559375600\",  \"InterfaceType\"   : \"4\",  \"OpId\"            : \"40051860\",  \"CountyCode\"      : \"4001\",  \"OrgId\"           : \"\",  \"ClientIP\"        : \"\",  \"TransactionTime\" : \"20150309140559\",  \"RegionCode\"      : \"400\" }}";
		String key = "1F26729F19CAF901A855C0420882CC85";

		String des = encryptDES3(key,"", src);
		String src3 = decryptDES3(key,"", des);

		System.out.println(src3);*/
		String key = "1F26729F19CAF901A855C0420882CC85";
		String des1 = "e63b2c0bb8d30c7ef592f665f9025de3ee2f6193cccd7791eefa1bbd6ee5c14a73ed213c17f85a59d2dbcbca3c586c943fa3e5f1169cc16021dcc07d77ffb5a03a08225e3b75d666b55f904dda8a266a24561ab234a5774eaaf2a2423c0d8ad53d7f5281aff4076bb755be673ab2bcada0ccfdf6aac6ca90986f8ce3829b5794";
		System.out.println(decryptDES3(key,"",des1));

	}

	/**
	 * 在Json报文中获取指定参数
	 */

	private static String getParamValue(String inPackage, String paramKey){
		String value = null;

		if( StringUtils.isNotBlank(inPackage) && StringUtils.isNotBlank(paramKey) ) {
			int index = inPackage.indexOf(paramKey);

			if( index<0 ) {
				index = inPackage.indexOf(paramKey);
			}
			if( index>0 ) {
				index = inPackage.indexOf(':', index);
			}
			int begin=0, end=0;

			//字符串分隔开始
			if( index>0 ) {
				begin = inPackage.indexOf('"', index);
			}

			//括号数量标记
			int braceflag = 0;

			//如果参数由括号包裹
			if(inPackage.indexOf('{', index)>0&&inPackage.indexOf('{', index)<inPackage.indexOf('"',index)){
				begin = inPackage.indexOf('{', index+1);
				index = inPackage.indexOf('{', index);

				braceflag = 1;
				//遇到一个左括号brace标记+1，遇到一个右括号brace标记-1
				for(int j =1;(index+j )< inPackage.length();j++){
					int tempIndex = index +j;
					if(inPackage.charAt(tempIndex)=='}'){
						braceflag --;
					}
					if(inPackage.charAt(tempIndex)=='{'){
						braceflag ++;
					}
					if(braceflag == 0){
						end = tempIndex;
						break;
					}
				}

				value = inPackage.substring(begin, end+1);

			}else { //字符串没有被括号包裹
				if( begin>0 ) {
					end = inPackage.indexOf('"', begin + 1);
				}
				if( end>0 ) {
					value = inPackage.substring(begin + 1, end);
				}
			}
		}

		return value;
	}



}
